package com.yonyou.pmclouds.basecom.util;

import com.yonyou.pmclouds.basecom.entity.TreeVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Array;
import java.util.*;

/**
 * @Author chulf
 * @Date 2020/3/17
 * @Description 对应的树形结构对象的工具类
 * 1.构建树形结构  2.返回对应的权限节点 3.返回对应的权限树 4.设置树根节点的负责人flag
 **/
public class TreeVOUtil {


    /**
     *
     * @param userId
     * @param tree
     * @return 所有有权限的末级节点
     */
    public static List<TreeVO> getLastNodeVOByManager(String userId,List<? extends TreeVO> tree){

        return getLastNodeVOByManager(userId,null,tree,null,true);
    }

    /**
     * @param userId
     * @param parent
     * @param tree    树
     * @param treeVOS 每个根节点有权限的节点集合
     * @param flag    是否所有的节点负责人都为空 只有根节点有这个标志
     * @return 所有有权限的末级节点
     */
    private static List<TreeVO> getLastNodeVOByManager(String userId, TreeVO parent, List<? extends TreeVO> tree, List<TreeVO> treeVOS, boolean flag) {

        ArrayList<TreeVO> result = null;
        int n = 0;
        for (TreeVO treeVO : tree) {
            List<TreeVO> childList = treeVO.getChild() == null ? new ArrayList<TreeVO>() : Arrays.asList(treeVO.getChild());
            if (treeVO.getPkParent() == null) {
                if ((userId.equals(treeVO.getManager()) || flag)
                        && treeVO.getChild() == null) {
                    treeVOS = new ArrayList<>();
                    treeVOS.add(treeVO);
                }else {
                    //每个根节点创建一个末级节点集合
                    treeVOS = getLastNodeVOByManager(userId, treeVO, childList, new ArrayList<TreeVO>(), treeVO.getNoManagerFlag());
                }
            } else {
                if (treeVO.getManager() == null) treeVO.setManager(parent.getManager());
                treeVOS = getLastNodeVOByManager(userId, treeVO, childList, treeVOS, flag);
                if ((userId.equals(treeVO.getManager()) || flag)
                        && treeVO.getChild() == null) treeVOS.add(treeVO);
            }
            //找到符合数据的末级节点添加到集合
            if (treeVO.getPkParent() == null) {
                if (treeVOS != null && !treeVOS.isEmpty()) {
                    if (result == null) result = new ArrayList<>();

                    result.addAll(treeVOS);
                }
                if (++n == tree.size()) treeVOS = result;
            }
        }
        return treeVOS;
    }

    /**
     *
     * @param userId
     * @param tree
     * @return 返回所有有权限的树节点
     */
    public static List<TreeVO> getTreeVOByManager(String userId,List<? extends TreeVO> tree){
        return getTreeVOByManager(userId,null,tree,null,true);
    }

    /**
     * @param userId
     * @param parent
     * @param tree
     * @param treeVOS 每个根节点对应的权限集合
     * @param flag    是否所有的节点负责人都为空 只有根节点有这个标志
     * @return 返回所有有权限的树节点
     */
    private static List<TreeVO> getTreeVOByManager(String userId, TreeVO parent, List<? extends TreeVO> tree, List<TreeVO> treeVOS, Boolean flag) {
        /**
         *  每个根节点找到对应的权限树就结束
         */
        ArrayList<TreeVO> result = null;
        int n = 0;
        for (TreeVO treeVO : tree) {
            //当为数据且所有计划节点负责人为空时
            if (treeVO.getPkParent() == null && treeVO.getNoManagerFlag()) {
                if (result == null) result = new ArrayList<>();
                result.add(treeVO);
                if (++n == tree.size()) treeVOS = result;
                continue;
            }

            List<TreeVO> childList = treeVO.getChild() == null ? new ArrayList<TreeVO>() : Arrays.asList(treeVO.getChild());
            if (treeVO.getPkParent() == null) treeVOS = new ArrayList<>();

            if (userId.equals(treeVO.getManager())) {
                treeVOS.add(treeVO);
            } else {
                if (treeVO.getManager() == null) treeVO.setManager(parent == null ? null : parent.getManager());
                treeVOS = (ArrayList<TreeVO>) getTreeVOByManager(userId, treeVO, childList, treeVOS, true);
            }

            //找到符合数据的树
            if (treeVO.getPkParent() == null) {
                if (treeVOS != null && !treeVOS.isEmpty()) {

                    if (result == null) result = new ArrayList<>();
                    result.addAll(treeVOS);
                }
                if (++n == tree.size()) treeVOS = result;
            }
        }
        return treeVOS;
    }


    /**
     * @param allVOs 当前的所有节点
     * @return 返回对应的树结构根节点
     */

    public static List<TreeVO> buildTree(TreeVO[] allVOs) {
        // 构造树
        Map<String, List<TreeVO>> childMap = new HashMap<>();
        for (TreeVO vo : allVOs) {
            String parent = vo.getPkParent();
            if (StringUtils.isEmpty(parent)) {
                parent = StringUtils.EMPTY;
            }
            List<TreeVO> children = childMap.get(parent);
            if (children == null) {
                children = new ArrayList<>();
                childMap.put(parent, children);
            }
            children.add(vo);
        }
        for (TreeVO vo : allVOs) {
            List<TreeVO> children = childMap.get(vo.getPk());
            if (children != null) {
                vo.setChild((TreeVO[]) Array.newInstance(vo.getClass(),children.size()));
            }
        }
        List<TreeVO> result = childMap.get(StringUtils.EMPTY);

        return result;
    }


    /**
     * 每个树根节点设置 是否所有节点没有负责人
     *
     * @param finalTreeVO 树根节点
     * @param tree        树
     */
    public static void setNoManagerFlag(TreeVO finalTreeVO, List<? extends TreeVO> tree) {
        for (TreeVO treeVO : tree) {
            List<TreeVO> childList = treeVO.getChild() == null ? new ArrayList<TreeVO>() : Arrays.asList(treeVO.getChild());
            if (treeVO.getPkParent() == null) setNoManagerFlag(treeVO, childList);
            else {
                setNoManagerFlag(finalTreeVO, childList);
                if (treeVO.getManager() != null && !StringUtils.isEmpty(treeVO.getManager())) {
                    finalTreeVO.setNoManagerFlag(false);
                }
            }
        }
    }
}
